<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JDK vs Spring @Transactional 注解</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        body {
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            color: #333;
            line-height: 1.6;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
            overflow: hidden;
        }

        header {
            background: #4b6cb7;
            color: white;
            padding: 30px;
            text-align: center;
        }

        h1 {
            font-size: 2.5rem;
            margin-bottom: 10px;
        }

        .subtitle {
            font-size: 1.2rem;
            opacity: 0.9;
        }

        .content {
            display: flex;
            flex-wrap: wrap;
            padding: 20px;
        }

        .comparison {
            flex: 1;
            min-width: 300px;
            padding: 20px;
        }

        .code-examples {
            flex: 1;
            min-width: 300px;
            padding: 20px;
            background: #f8f9fa;
            border-radius: 10px;
        }

        .card {
            background: white;
            border-radius: 10px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
            padding: 20px;
            margin-bottom: 20px;
        }

        h2 {
            font-size: 1.8rem;
            margin-bottom: 20px;
            color: #343a40;
            border-bottom: 2px solid #e9ecef;
            padding-bottom: 10px;
        }

        h3 {
            font-size: 1.4rem;
            margin: 15px 0;
            color: #4b6cb7;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            margin: 20px 0;
        }

        th, td {
            padding: 15px;
            text-align: left;
            border-bottom: 1px solid #e9ecef;
        }

        th {
            background-color: #f8f9fa;
            font-weight: 600;
        }

        tr:hover {
            background-color: #f8f9fa;
        }

        .feature {
            font-weight: 600;
            color: #495057;
        }

        .jdk-support {
            color: #dc3545;
            text-align: center;
        }

        .spring-support {
            color: #28a745;
            text-align: center;
        }

        .code-block {
            background: #2d2d2d;
            color: #f8f9fa;
            padding: 20px;
            border-radius: 8px;
            margin: 15px 0;
            overflow-x: auto;
            font-family: 'Courier New', monospace;
        }

        .keyword {
            color: #cc99cd;
        }

        .annotation {
            color: #f08d49;
        }

        .class {
            color: #7ec699;
        }

        .method {
            color: #f8c555;
        }

        .comment {
            color: #999;
        }

        .btn {
            display: inline-block;
            background: #4b6cb7;
            color: white;
            padding: 12px 25px;
            border-radius: 8px;
            text-decoration: none;
            font-weight: 600;
            margin-top: 10px;
            transition: background 0.3s;
        }

        .btn:hover {
            background: #3a5999;
        }

        .conclusion {
            background: #e9ecef;
            padding: 30px;
            border-radius: 10px;
            margin-top: 20px;
        }

        @media (max-width: 768px) {
            .content {
                flex-direction: column;
            }
        }

        .icon {
            font-size: 24px;
            margin-right: 10px;
            vertical-align: middle;
        }
    </style>
</head>
<body>
<div class="container">
    <header>
        <h1><i class="fas fa-code icon"></i> JDK vs Spring @Transactional 注解</h1>
        <div class="subtitle">全面比较两种事务注解的区别与使用场景</div>
    </header>

    <div class="content">
        <div class="comparison">
            <h2><i class="fas fa-balance-scale icon"></i>特性对比</h2>

            <div class="card">
                <h3>JDK的@Transactional注解</h3>
                <p>Java EE（现Jakarta EE）提供的注解，基于JTA（Java Transaction API）实现。</p>

                <table>
                    <tr>
                        <th class="feature">特性</th>
                        <th class="jdk-support">JDK支持</th>
                    </tr>
                    <tr>
                        <td>基于接口的代理</td>
                        <td class="jdk-support"><i class="fas fa-check"></i></td>
                    </tr>
                    <tr>
                        <td>基于类的代理</td>
                        <td class="jdk-support"><i class="fas fa-times"></i></td>
                    </tr>
                    <tr>
                        <td>声明式事务管理</td>
                        <td class="jdk-support"><i class="fas fa-check"></i></td>
                    </tr>
                    <tr>
                        <td>编程式事务管理</td>
                        <td class="jdk-support"><i class="fas fa-check"></i></td>
                    </tr>
                    <tr>
                        <td>事务传播行为</td>
                        <td class="jdk-support"><i class="fas fa-check"></i></td>
                    </tr>
                    <tr>
                        <td>事务隔离级别</td>
                        <td class="jdk-support"><i class="fas fa-check"></i></td>
                    </tr>
                    <tr>
                        <td>回滚规则配置</td>
                        <td class="jdk-support"><i class="fas fa-times"></i></td>
                    </tr>
                    <tr>
                        <td>与Spring框架集成</td>
                        <td class="jdk-support"><i class="fas fa-times"></i></td>
                    </tr>
                </table>
            </div>

            <div class="card">
                <h3>Spring的@Transactional注解</h3>
                <p>Spring框架提供的事务管理注解，功能更强大，配置更灵活。</p>

                <table>
                    <tr>
                        <th class="feature">特性</th>
                        <th class="spring-support">Spring支持</th>
                    </tr>
                    <tr>
                        <td>基于接口的代理</td>
                        <td class="spring-support"><i class="fas fa-check"></i></td>
                    </tr>
                    <tr>
                        <td>基于类的代理（CGLIB）</td>
                        <td class="spring-support"><i class="fas fa-check"></i></td>
                    </tr>
                    <tr>
                        <td>声明式事务管理</td>
                        <td class="spring-support"><i class="fas fa-check"></i></td>
                    </tr>
                    <tr>
                        <td>编程式事务管理</td>
                        <td class="spring-support"><i class="fas fa-check"></i></td>
                    </tr>
                    <tr>
                        <td>事务传播行为</td>
                        <td class="spring-support"><i class="fas fa-check"></i></td>
                    </tr>
                    <tr>
                        <td>事务隔离级别</td>
                        <td class="spring-support"><i class="fas fa-check"></i></td>
                    </tr>
                    <tr>
                        <td>回滚规则配置</td>
                        <td class="spring-support"><i class="fas fa-check"></i></td>
                    </tr>
                    <tr>
                        <td>与Spring框架集成</td>
                        <td class="spring-support"><i class="fas fa-check"></i></td>
                    </tr>
                </table>
            </div>
        </div>

        <div class="code-examples">
            <h2><i class="fas fa-laptop-code icon"></i>代码示例</h2>

            <div class="card">
                <h3>JDK @Transactional 示例</h3>
                <div class="code-block">
                    <span class="keyword">import</span> javax.transaction.Transactional;<br>
                    <br>
                    <span class="annotation">@Transactional</span>(<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;value = <span class="class">TransactionTm</span>.SYSTEM_DEFAULT,<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;rollbackOn = {<span class="class">Exception</span>.<span class="keyword">class</span>}<br>
                    )<br>
                    <span class="keyword">public</span> <span class="class">class</span> <span class="class">BankServiceJdk</span> {<br>
                    <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span> <span class="keyword">void</span> <span class="method">transferMoney</span>(<span class="class">String</span> fromAcc, <span class="class">String</span> toAcc, <span class="keyword">double</span> amount) {<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// 业务逻辑</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="class">System</span>.out.println(<span class="string">"Transfering money with JDK @Transactional"</span>);<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;}<br>
                    }
                </div>
            </div>

            <div class="card">
                <h3>Spring @Transactional 示例</h3>
                <div class="code-block">
                    <span class="keyword">import</span> org.springframework.transaction.annotation.Transactional;<br>
                    <br>
                    <span class="annotation">@Transactional</span>(<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;propagation = <span class="class">Propagation</span>.REQUIRED,<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;isolation = <span class="class">Isolation</span>.DEFAULT,<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;readOnly = <span class="keyword">false</span>,<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;timeout = 30,<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;rollbackFor = {<span class="class">Exception</span>.<span class="keyword">class</span>},<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;noRollbackFor = {<span class="class">RuntimeException</span>.<span class="keyword">class</span>}<br>
                    )<br>
                    <span class="keyword">public</span> <span class="class">class</span> <span class="class">BankServiceSpring</span> {<br>
                    <br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span> <span class="keyword">void</span> <span class="method">transferMoney</span>(<span class="class">String</span> fromAcc, <span class="class">String</span> toAcc, <span class="keyword">double</span> amount) {<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">// 业务逻辑</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="class">System</span>.out.println(<span class="string">"Transfering money with Spring @Transactional"</span>);<br>
                    &nbsp;&nbsp;&nbsp;&nbsp;}<br>
                    }
                </div>
            </div>

            <div class="card">
                <h3>Spring配置示例</h3>
                <div class="code-block">
                    <span class="comment">&lt;!-- 在Spring配置文件中启用注解驱动的事务管理 --&gt;</span><br>
                    <span class="tag">&lt;tx:annotation-driven</span> <span class="attr">transaction-manager</span>=<span class="string">"transactionManager"</span><span class="tag">/&gt;</span><br>
                    <br>
                    <span class="comment">&lt;!-- 定义事务管理器 --&gt;</span><br>
                    <span class="tag">&lt;bean</span> <span class="attr">id</span>=<span class="string">"transactionManager"</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="attr">class</span>=<span class="string">"org.springframework.jdbc.datasource.DataSourceTransactionManager"</span><span class="tag">&gt;</span><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;property</span> <span class="attr">name</span>=<span class="string">"dataSource"</span> <span class="attr">ref</span>=<span class="string">"dataSource"</span><span class="tag">/&gt;</span><br>
                    <span class="tag">&lt;/bean&gt;</span><br>
                    <br>
                    <span class="comment">&lt;!-- 使用@Transactional注解的类 --&gt;</span><br>
                    <span class="tag">&lt;bean</span> <span class="attr">id</span>=<span class="string">"bankService"</span> <span class="attr">class</span>=<span class="string">"com.example.BankServiceSpring"</span><span class="tag">/&gt;</span>
                </div>
            </div>
        </div>
    </div>

    <div class="conclusion">
        <h2><i class="fas fa-lightbulb icon"></i>总结与建议</h2>
        <div class="card">
            <h3>主要区别</h3>
            <ul>
                <li><strong>来源不同</strong>: JDK的注解来自javax.transaction，Spring的注解来自org.springframework.transaction.annotation</li>
                <li><strong>功能丰富度</strong>: Spring的@Transactional提供更多配置选项，如rollbackFor、noRollbackFor、readOnly等</li>
                <li><strong>代理机制</strong>: Spring支持基于接口和基于类的代理，JDK只支持基于接口的代理</li>
                <li><strong>集成度</strong>: Spring的注解与Spring框架无缝集成，提供更强大的事务管理能力</li>
            </ul>

            <h3>使用建议</h3>
            <ul>
                <li>在<strong>Spring项目</strong>中优先使用Spring的@Transactional注解</li>
                <li>在<strong>纯Java EE环境</strong>中可以使用JDK的@Transactional注解</li>
                <li>需要<strong>更精细的事务控制</strong>时使用Spring的注解</li>
                <li>考虑<strong>项目迁移</strong>时注意两种注解的兼容性</li>
            </ul>

            <a href="#" class="btn"><i class="fas fa-download icon"></i> 下载比较PDF</a>
        </div>
    </div>
</div>

<script>
    // 简单的交互效果
    document.addEventListener('DOMContentLoaded', function() {
        const cards = document.querySelectorAll('.card');
        cards.forEach(card => {
            card.addEventListener('mouseover', () => {
                card.style.transform = 'translateY(-5px)';
                card.style.transition = 'transform 0.3s ease';
            });

            card.addEventListener('mouseout', () => {
                card.style.transform = 'translateY(0)';
            });
        });

        const buttons = document.querySelectorAll('.btn');
        buttons.forEach(button => {
            button.addEventListener('click', (e) => {
                e.preventDefault();
                alert('下载功能仅作演示');
            });
        });
    });
</script>
</body>
</html>